package net.comfycastle.musicplayer;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

import android.database.Cursor;
import android.database.MatrixCursor;
import android.os.Bundle;
import android.provider.MediaStore.Audio;
import android.view.View;
import android.widget.ListView;

/**
 * 그룹의 목록을 출력하는 Fragment
 * @author ricale
 *
 */
public class GroupListFragment extends BaseListFragment {
	///////////
	//////////
	/////////   constant
	
	/** 객체 생성 당시 argument로 전달되는 bundle 객체에서 프래그먼트 아이디의 키값 */
	private static final String KEY_ID   = "FragAlbumList.keyId";
	/** 객체 생성 당시 argument로 전달되는 bundle 객체에서 그룹 종류(아티스트,장르,작곡가 등)의 키값 */
	private static final String KEY_KIND = "FragGroupList.keyKind";
	
	///////////
	//////////
	/////////   constructor
	
	/**
	 * FragGroupList의 인스턴스를 생성/반환하는 정적 메소드
	 * 인자를 받지 못하는 Fragment 클래스 생성자 대신 인자를 받는다.
	 * @param fragmentId 생성될 인스턴스의 고유 아이디
	 * @param kind 그룹의 종류
	 * @return FragGroupList의 인스턴스
	 */
	public static GroupListFragment newInstance(OBJECTID fragmentId, String kind) {
		GroupListFragment instance = new GroupListFragment();
		
		Bundle bundle = new Bundle();
		bundle.putString(KEY_ID,   fragmentId.name());
		bundle.putString(KEY_KIND, kind);
		instance.setArguments(bundle);
		
		return instance;
	} // end newInstance
	
	///////////
	//////////
	/////////   getter
	
	/**
	 * 이 인스턴스의 고유 아이디를 리턴한다.
	 * @return 이 인스턴스의 고유 아이디
	 */
	public OBJECTID getFragmentId() {
		return OBJECTID.valueOf(getArguments().getString(KEY_ID));
	} // end getFragmentId
	
	/**
	 * 그룹의 종류를 리턴한다.
	 * @return 그룹의 종류
	 */
	public String getKind() {
		return getArguments().getString(KEY_KIND);
	} // end getKind
	
	///////////
	//////////
	/////////   methods
	
	public String getTitleForWindow() {
		return null;
	}
	
	/**
	 * 기준(getKind())에 맞춰 리스트를 생성/등록한다.
	 */
	protected void setList() {
		String kind = getKind();
		
		Cursor cursor;
		if(kind.equals(MPApp.TAG_ARTIST)) {
			cursor = getCursorGroupByArtist();
		} else {
			cursor = getCursorGroupBy();
		} // end if
	    
	    GroupListMCAdapter adapter = new GroupListMCAdapter(getActivity(), cursor);
	    
	    if(kind.equals(MPApp.TAG_ARTIST)) {
			adapter.setViewState(GroupListMCAdapter.VIEWSTATE.ARTIST);
	    } else if(kind.equals(MPApp.TAG_GENRE)) {
			adapter.setViewState(GroupListMCAdapter.VIEWSTATE.GENRE);
	    } else { // keyTag.equals(MPApp.TAG_COMPOSER)
			adapter.setViewState(GroupListMCAdapter.VIEWSTATE.COMPOSER);
	    } // end if
	    
	    setListAdapter(adapter);
	} // end setList
	
	/**
	 * 아티스트를 제외한 그룹에 대한 리스트를 생성한다.
	 * @return 그룹의 리스트를 가리키는 Cursor
	 */
	private Cursor getCursorGroupBy() {
		String   kind    = getKind();
		String[] columns = new String[] { MPApp.TAG_ID, kind };
		
		Cursor       cursor = getActivity().getContentResolver().query(Audio.Media.EXTERNAL_CONTENT_URI, columns, null, null, kind);
		MatrixCursor result = new MatrixCursor(columns);
		
		String currentGroup = null;
		String lastGroup    = null;
		
		while(cursor != null && cursor.moveToNext()) {
			currentGroup = cursor.getString(cursor.getColumnIndex(kind));
			
			if(!currentGroup.equals(lastGroup)) {
				Object[] o = new Object[columns.length];
				for(int i = 0; i < columns.length; i++) {
					o[i] = cursor.getString(cursor.getColumnIndex(columns[i]));
				} // end for
				result.addRow(o);
				
				lastGroup = currentGroup;
			} // end if
		} // end while
		
		cursor.close();
		
		return result;
	} // end getCursorGroupBy
	
	/**
	 * 아티스트 구룹에 대한 리스트를 생성한다.
	 * @return 그룹의 리스트를 가리키는 Cursor
	 */
	private Cursor getCursorGroupByArtist()	{
		String[] columns = new String[] { MPApp.TAG_ID, MPApp.TAG_ARTIST, MPApp.TAG_ALBUMARTIST };
		Cursor   cursor  = getActivity().getContentResolver().query(Audio.Media.EXTERNAL_CONTENT_URI,
				                                                    columns,
				                                                    null,
				                                                    null,
				                                                    MPApp.TAG_ALBUMARTIST + "," + MPApp.TAG_ARTIST);
		
		List<Object[]> array = new ArrayList<Object[]>();
		String currentGroup = null;
		String lastGroup    = null;
		
		while(cursor != null && cursor.moveToNext()) {
			currentGroup = cursor.getString(cursor.getColumnIndex(MPApp.TAG_ALBUMARTIST));
			if(currentGroup == null || currentGroup.length() == 0) {
				currentGroup = cursor.getString(cursor.getColumnIndex(MPApp.TAG_ARTIST));
			} // end if
			
			if(!currentGroup.equals(lastGroup))	{
				Object[] o = new String[columns.length + 1];
				for(int i = 0; i < columns.length; i++) {
					o[i] = cursor.getString(cursor.getColumnIndex(columns[i]));
				} // end for
				o[o.length - 1] = currentGroup;
				
				array.add(o);
				
				lastGroup = currentGroup;
			} // end if
		} // end while
		cursor.close();
		
		Collections.sort(array, new Comparator<Object[]>() {
			public int compare(Object[] lhs, Object[] rhs) {
				String lhss = (String)lhs[lhs.length - 1];
				String rhss = (String)rhs[rhs.length - 1];
				
				return lhss.compareTo(rhss);
			} // end compare
		}); // end new Comparator<Object[]>()
		
		columns = new String[] {columns[0], columns[1], columns[2], MPApp.TAG_TITLEARTIST};
		MatrixCursor result = new MatrixCursor(columns);
		
		for(Object[] o : array) {
			result.addRow(o);
		} // end for
		
		return result;
	} // end getCursorGroupByArtist
	
	///////////
	//////////
	/////////   event listener & callback method
	
	/**
	 * 리스트가 클릭되었을 때의 콜백 메서드
	 */
	@Override
	public void onListItemClick(ListView l, View view, int position, long id) {		
		BaseListFragment.OnListItemClickListener lintener = (BaseListFragment.OnListItemClickListener)getActivity();
		lintener.onItemClick(getFragmentId(), l, view, position, id);
	} // end onListItemClick
} // end FragGroupList